// maak de linker global
var $bgpGameLinker = {};

$bgpGameLinker.load = function(moduleName, permutationsMap)
{
        // initialisatie
        var $wnd_0 = window, $doc_0 = document, gwtOnLoadFunc, bodyDone, base = '', metaProps = {}, values = [], providers = [], onLoadErrorFunc, propertyErrorFunc;
        if (!$wnd_0.__gwt_stylesLoaded)
        {
                $wnd_0.__gwt_stylesLoaded = {};
        }
        if (!$wnd_0.__gwt_scriptsLoaded)
        {
                $wnd_0.__gwt_scriptsLoaded = {};
        }

        // probeert de module te starten als het laden compleet is
        function maybeStartModule()
        {
                if (gwtOnLoadFunc && bodyDone)
                {
                        gwtOnLoadFunc(onLoadErrorFunc, moduleName, base);
                }
        }

        // bepaalt de base dir van het script (hardcoded)
        function computeScriptBase()
        {
                base = "http://" + window.location.host + "/resources/" + moduleName + "/";
        }

        // loopt alle meta tags na voor properties etc.
        function processMetas()
        {
                var metas = document.getElementsByTagName('meta');
                for ( var i = 0, n = metas.length; i < n; ++i)
                {
                        var meta = metas[i], name_0 = meta.getAttribute('name'), content;
                        if (name_0)
                        {
                                if (name_0 == 'gwt:property')
                                {
                                        content = meta.getAttribute('content');
                                        if (content)
                                        {
                                                var value, eq = content.indexOf('=');
                                                if (eq >= 0)
                                                {
                                                        name_0 = content.substring(0, eq);
                                                        value = content.substring(eq + 1);
                                                } else
                                                {
                                                        name_0 = content;
                                                        value = '';
                                                }
                                                metaProps[name_0] = value;
                                        }
                                } else if (name_0 == 'gwt:onPropertyErrorFn')
                                {
                                        content = meta.getAttribute('content');
                                        if (content)
                                        {
                                                try
                                                {
                                                        propertyErrorFunc = eval(content);
                                                } catch (e)
                                                {
                                                        alert('Bad handler "' + content + '" for "gwt:onPropertyErrorFn"');
                                                }
                                        }
                                } else if (name_0 == 'gwt:onLoadErrorFn')
                                {
                                        content = meta.getAttribute('content');
                                        if (content)
                                        {
                                                try
                                                {
                                                        onLoadErrorFunc = eval(content);
                                                } catch (e)
                                                {
                                                        alert('Bad handler "' + content + '" for "gwt:onLoadErrorFn"');
                                                }
                                        }
                                }
                        }
                }
        }

        // bepaal de waarde van een property uit de meta-tag of automagisch uit de propertyproviders
        function computePropValue(propName)
        {
                var value = providers[propName](), allowedValuesMap = values[propName];
                if (value in allowedValuesMap)
                {
                        return value;
                }
                var allowedValuesList = [];
                for (var k in allowedValuesMap)
                {
                        allowedValuesList[allowedValuesMap[k]] = k;
                }
                if (propertyErrorFunc)
                {
                        propertyErrorFunc(propName, allowedValuesList, value);
                }
                throw null;
        }

        // property provider voor automatische bepaling van de user agent
        providers['user.agent'] = function()
        {
                var ua = navigator.userAgent.toLowerCase();
                var makeVersion = function(result)
                {
                        return parseInt(result[1]) * 1000 + parseInt(result[2]);
                };
                if (ua.indexOf('opera') != -1)
                {
                        return 'opera';
                } else if (ua.indexOf('webkit') != -1)
                {
                        return 'safari';
                } else if (ua.indexOf('msie') != -1)
                {
                        if (document.documentMode >= 8)
                        {
                                return 'ie8';
                        } else
                        {
                                var result_0 = /msie ([0-9]+)\.([0-9]+)/.exec(ua);
                                if (result_0 && result_0.length == 3)
                                {
                                        var v = makeVersion(result_0);
                                        if (v >= 6000)
                                        {
                                                return 'ie6';
                                        }
                                }
                        }
                } else if (ua.indexOf('gecko') != -1)
                {
                        var result_0 = /rv:([0-9]+)\.([0-9]+)/.exec(ua);
                        if (result_0 && result_0.length == 3)
                        {
                                if (makeVersion(result_0) >= 1008)
                                        return 'gecko1_8';
                        }
                        return 'gecko';
                }
                return 'unknown';
        };

        // alle mogelijke waarden voor de user.agent property
        values['user.agent'] =
        {
            gecko : 0,
            gecko1_8 : 1,
            ie6 : 2,
            ie8 : 3,
            opera : 4,
            safari : 5
        };

        // bepaal de base dir van het script (hardcoded)
        computeScriptBase();

        // loop alle meta tags na voor properties etc.
        processMetas();

        // bepaal de strongname van de permutatie van deze browser
        var strongName;
        try
        {
                strongName = permutationsMap[computePropValue('user.agent')];
        } catch (e)
        {
                return;
        }

        // voor alle browsers geschikte, 'bulletproof' manier om te kijken of het document klaar is met laden
        var onBodyDoneTimerId;
        function onBodyDone()
        {
                if (!bodyDone)
                {
                        bodyDone = true;
                        maybeStartModule();
                        if ($doc_0.removeEventListener)
                        {
                                $doc_0.removeEventListener('DOMContentLoaded', onBodyDone, false);
                        }
                        if (onBodyDoneTimerId)
                        {
                                clearInterval(onBodyDoneTimerId);
                        }
                }
        }
        if ($doc_0.addEventListener)
        {
                $doc_0.addEventListener('DOMContentLoaded', function()
                {
                        onBodyDone();
                }, false);
        }
        var onBodyDoneTimerId = setInterval(function()
        {
                if (/loaded|complete/.test($doc_0.readyState))
                {
                        onBodyDone();
                }
        }, 50);

        // voeg een onScriptLoad methode toe, deze wordt aangeroepen aan het eind van de te laten module
        // en start de module als het document klaar is met laden
        $bgpGameLinker.load.onScriptLoad = function(pGwtOnLoadFunc)
        {
                gwtOnLoadFunc = pGwtOnLoadFunc;
                maybeStartModule();
        };

        // voegt een javascript tag aan een element toe
        function addJavascript(jsname, parent)
        {
                var e = document.createElement('script');
                e.setAttribute('type', 'text/javascript');
                e.setAttribute('src', jsname);
                parent.appendChild(e);
        }

        // voegt een link tag naar een stylesheet aan een element toe
        function addStylesheet(ssname, parent)
        {
                var e = document.createElement('link');
                e.setAttribute('rel', 'stylesheet');
                e.setAttribute('type', 'text/css');
                e.setAttribute('href', ssname);
                parent.appendChild(e);
        }

        // haal oude module weg
        var modulescripts = $doc_0.getElementById('modulescripts');
        var modulestyles = $doc_0.getElementById('modulestyles');
        modulescripts.innerHTML = "";
        modulestyles.innerHTML = "";

        // voeg de uitendelijk geselecteerde permutatie toe aan de div id=modulescripts van het document
        // aan het einde van die permutatie wordt de gwtOnLoadFunc pas meegegeven
        addStylesheet(base + 'style.css', modulestyles);
        addJavascript(base + strongName + '.cache.js', modulescripts);
};